import { Context } from 'koa';
import { AppContext, TenantStatus } from '@/types';
import TenantService from '@/services/TenantService';
import { validate, commonSchemas } from '@/utils/validator';
import * as response from '@/utils/response';
import Joi from 'joi';

/**
 * 租户控制器
 */
export class TenantController {
  /**
   * 创建租户
   */
  async create(ctx: Context) {
    const appCtx = ctx as AppContext;

    const schema = Joi.object({
      name: Joi.string().min(2).max(255).required(),
      subdomain: commonSchemas.subdomain.required(),
      planId: commonSchemas.uuid.required(),
      adminEmail: commonSchemas.email.required(),
      adminPassword: commonSchemas.password.required(),
      adminFirstName: Joi.string().max(100),
      adminLastName: Joi.string().max(100),
    });

    interface CreateTenantData {
      name: string;
      subdomain: string;
      planId: string;
      adminEmail: string;
      adminPassword: string;
      adminFirstName?: string;
      adminLastName?: string;
    }

    const data = await validate<CreateTenantData>(ctx.request.body as any, schema);

    const tenant = await TenantService.createTenant(
      data,
      appCtx.state.user?.id,
    );

    response.created(ctx, tenant, '租户创建成功');
  }

  /**
   * 获取租户详情
   */
  async getById(ctx: Context) {
    const { id } = ctx.params;

    const tenant = await TenantService.getTenantById(id);

    if (!tenant) {
      return response.notFound(ctx, '租户不存在');
    }

    response.success(ctx, tenant);
  }

  /**
   * 获取租户列表
   */
  async list(ctx: Context) {
    const schema = Joi.object({
      page: Joi.number().integer().min(1).default(1),
      pageSize: Joi.number().integer().min(1).max(100).default(20),
      status: Joi.string().valid(...Object.values(TenantStatus)),
      planId: commonSchemas.uuid,
      search: Joi.string().max(255),
    });

    interface ListFilter {
      page: number;
      pageSize: number;
      status?: string;
      planId?: string;
      search?: string;
    }

    const filter = await validate<ListFilter>(ctx.query as any, schema);  

    const result = await TenantService.listTenants(filter as any);

    response.paginated(
      ctx,
      result.data,
      result.pagination.total,
      result.pagination.page,
      result.pagination.pageSize,
    );
  }

  /**
   * 更新租户
   */
  async update(ctx: Context) {
    const appCtx = ctx as AppContext;
    const { id } = ctx.params;

    const schema = Joi.object({
      name: Joi.string().min(2).max(255),
      planId: commonSchemas.uuid,
      status: Joi.string().valid(...Object.values(TenantStatus)),
      config: Joi.object(),
      trialEndsAt: Joi.date().iso(),
      subscriptionEndsAt: Joi.date().iso(),
    });

    interface UpdateTenantData {
      name?: string;
      planId?: string;
      status?: string;
      config?: Record<string, any>;
      trialEndsAt?: Date;
      subscriptionEndsAt?: Date;
    }

    const data = await validate<UpdateTenantData>(ctx.request.body as any, schema);

    const tenant = await TenantService.updateTenant(
      id,
      data as any,
      appCtx.state.user?.id,
    );

    response.success(ctx, tenant, '租户更新成功');
  }

  /**
   * 激活租户
   */
  async activate(ctx: Context) {
    const appCtx = ctx as AppContext;
    const { id } = ctx.params;

    const tenant = await TenantService.activateTenant(
      id,
      appCtx.state.user?.id,
    );

    response.success(ctx, tenant, '租户已激活');
  }

  /**
   * 暂停租户
   */
  async suspend(ctx: Context) {
    const appCtx = ctx as AppContext;
    const { id } = ctx.params;

    const tenant = await TenantService.suspendTenant(
      id,
      appCtx.state.user?.id,
    );

    response.success(ctx, tenant, '租户已暂停');
  }

  /**
   * 删除租户
   */
  async delete(ctx: Context) {
    const appCtx = ctx as AppContext;
    const { id } = ctx.params;

    await TenantService.deleteTenant(id, appCtx.state.user?.id);

    response.success(ctx, null, '租户已删除');
  }

  /**
   * 获取租户统计信息
   */
  async getStats(ctx: Context) {
    const { id } = ctx.params;

    const stats = await TenantService.getTenantStats(id);

    response.success(ctx, stats);
  }
}

export default new TenantController();

